#include "netdisk3.h"

char* format(const char *p);//格式化，给字符加上双引号和，
int idtoPath(int id,char *path,MYSQL *mysql);
int isDir(int id, MYSQL *mysql);
int mkdirFunc(int id_now,const char *arg, const char *user,MYSQL *mysql);
char* format(const char *p)//格式化，给字符加上双引号和，
{
    char* str = (char*) calloc (1024,sizeof(char));
    strcpy(str,"'");
    strcat(str,p);
    strcat(str,"',");
    printf("%s\n",str);
    return str;
}
//根据id找Path
int idtoPath(int id,char *path,MYSQL *mysql)
{
    char sql[1024] = "select path from virtual_file where id = ";

    char str[20] = {0};
    sprintf(str,"%d",id);
    strcat(sql,str);
    int qret = mysql_query(mysql,sql);
    if(qret != 0){
        fprintf(stderr,"error 2:%s\n", mysql_error(mysql));
        return -1;
    }
    MYSQL_RES *res = mysql_store_result(mysql);
    // printf("total rows = %lu\n",mysql_num_rows(res));
    MYSQL_ROW row;
    row = mysql_fetch_row(res);
    // printf("%s\n",row[0]);
    if(strcmp(row[0], "/") != 0){
        strcpy(path,row[0]);
    }
}
//判断id对应的文件是否是目录,0表示不是目录，1表示是目录
int isDir(int id, MYSQL *mysql)
{
    //将int型转换成字符串型
    char str[20] = {0};
    sprintf(str,"%d",id);
    //先判断是否是目录
    char sql[1024] = "select id from virtual_file where type = 'd' and id = ";
    strcat(sql,str);
    int qret = mysql_query(mysql,sql);
    if(qret != 0){
        fprintf(stderr,"error:%s\n", mysql_error(mysql));
        return -1;
    }
    MYSQL_RES *res = mysql_store_result(mysql);
    printf("total rows = %lu\n",mysql_num_rows(res));
    if((int)mysql_num_rows(res) == 0)
        return 0;//表示不是目录
    return 1;
}
//判断这个id对应的文件或目录的tomb是否为1，是返回1，否返回0
int isTomb1(int id, MYSQL *mysql)
{
    //将int型转换成字符串型
    char str[20] = {0};
    sprintf(str,"%d",id);

    char sql[4096];
    bzero(sql,sizeof(sql));
    strcpy(sql,"select tomb from virtual_file where id =  ");
    strcat(sql,str);
    printf("%s\n",sql);
    int qret = mysql_query(mysql,sql);
    if(qret != 0){
        fprintf(stderr,"error:%s\n", mysql_error(mysql));
        return -1;
    }
    MYSQL_RES *res = mysql_store_result(mysql);
    printf("total rows = %lu\n",mysql_num_rows(res));
    MYSQL_ROW row;
    row = mysql_fetch_row(res);
    printf("tomb is %s\n",row[0]);
    if( strcmp(row[0],"0") == 0)
        return 0;//表示tomb为0；
    else
        return 1;//表示tomb为1；

}
//mkdir功能，需要传入当前目录id，待创建的目录名(可包含路径)，当前用户user，数据库链接mysql
int mkdirFunc(int id_now,const char *arg, const char *user,MYSQL *mysql)
{
    //设置返回值，在多参数情况下只保存最后一次失败的值
    int return_value = 0;
    char str[1024];
    strcpy(str,arg);
    int idx = 0;
    char *p[1024];
    p[idx++] = strtok(str," ");
    //printf("%s\n",p[0]);
    while((p[idx++] = strtok(NULL," ")) != NULL);
    //printf("%s\n",p[idx-1]);
    for(int i = 0; i < idx && p[i] != NULL; i++)
    {
        //去掉最后要创建的文件夹名，将剩余字符串（可能为NULL），传给getAbPathId
        char name[1024] = {0};
        char dirname[1024] = {0};
        strcpy(name,p[i]);
        int len = strlen(name);
        for(int i = len-1,j = 0; i>=0;i--,j++)
            if(name[i]!='/')
            {
                dirname[j] = name[i];
                name[i] = '\0';
            }  
            else
                break;
        //将dirname逆置成正确的顺序
        for(int i = 0,j = strlen(dirname) - 1; i <= j; i++,j--)
        {
            char tmp = dirname[i];
            printf("%c\n",tmp);
            dirname[i] = dirname[j];
            dirname[j] = tmp;
        }
        printf("%s111\n",name);
        printf("%s\n",dirname);
        //传给getAbsolutePathId的name是去掉了要创建的文件夹的名字
        int id = getAbsolutePathId(id_now,name,user,mysql);
        printf("%d\n",id);
        //int id = id_now;
        //如果id对应的目录不存在，则创建失败
        if(id == -1)
        {
            return_value = -1;
            break;
        }
        //如果id对应的是文件，则创建失败；
        if(isDir(id,mysql) == 0)
        {
            return_value = -1;
            break;
        }
        //如果id对应的目录不存在(tomb=1)，则将tomb置为1；
        if(isTomb1(id,mysql) == 1)
        {
            char sql[1024] = "update virtual_file set tomb = 1 where id = ";
            char str[20] = {0};
            sprintf(str,"%d",id);
            strcat(sql,str);
            int qret = mysql_query(mysql,sql);
            if(qret != 0){
                fprintf(stderr,"error:%s\n", mysql_error(mysql));
                {
                    return_value = -1;
                    break;
                }
            }
            //return_value = -1;
            break;
        }
        //通过id找到当前目录的path
        char path1[1024] = {0};
        idtoPath(id,path1,mysql);
        printf("%s\n",path1);
        char curPath[1024] = {0};
        strcpy(curPath,path1);
        printf("%s\n",curPath);
        //char sql[] = "update pet set species='puppey' where name = 'Bowser';";
        char pre_sql[4096] = "insert into virtual_file (name,type,pre_id,path,user,md5,tomb) values(";

        //curPath存储创建目录成功之后path的内容
        if(strcmp(path1,"/") != 0)
            strcat(curPath,"/");
        strcat(curPath,dirname);
        printf("%s\n",curPath);

        //声明变量存储name,id,path,user
        char *pre_name;
        char *pre_path;
        char *pre_user;
        char *pre_tail = "null,'0');";
        char pre_id2[10] = {0};

        //格式化name,id,path,user,
        pre_name = format(dirname);
        pre_path = format(curPath);
        pre_user = format(user);
        char str[20] = {0};
        sprintf(str,"%d",id);
        strcpy(pre_id2,str);
        strcat(pre_id2,",");
        char pre_type[] = "'d',";

        //开始拼接sql字符串
        strcat(pre_sql,pre_name);
        strcat(pre_sql,pre_type);
        strcat(pre_sql,pre_id2);
        strcat(pre_sql,pre_path);
        strcat(pre_sql,pre_user);
        strcat(pre_sql,pre_tail);
        printf("%s\n",pre_sql);
        //char sql[] = "insert into diretory (name,type,pre_id,path,user,md5,tomb) values('dir2','d',1,'/dir2','user1',null,'0');";
        int qret = mysql_query(mysql,pre_sql);
        if(qret != 0){
            fprintf(stderr,"error:%s\n", mysql_error(mysql));
            {
                return_value = -1;
                break;
            }
        }
    }
    return return_value;
}

//文件夹判空,1表示空，0表示非空
int isEmpty(int id,MYSQL *mysql)
{
    //判断目录是否为空
    //将int型转换成字符串型
    char str[20] = {0};
    sprintf(str,"%d",id);

    char sql[4096];
    bzero(sql,sizeof(sql));
    strcpy(sql,"select id from virtual_file where tomb != 1 and pre_id =  ");
    strcat(sql,str);
    printf("%s\n",sql);
    int qret = mysql_query(mysql,sql);
    if(qret != 0){
        fprintf(stderr,"error:%s\n", mysql_error(mysql));
        return -1;
    }
    MYSQL_RES *res = mysql_store_result(mysql);
    printf("total rows = %lu\n",mysql_num_rows(res));
    if((int)mysql_num_rows(res) == 0)
        return 1;//表示目录为空
    else
        return 0;//表示目录非空
}
//删除文件夹，先判断目录是否存在，不存在删除失败，非空则删除失败，非文件夹删除失败，否则将对应id的tomb参数置为1；
int rmdirFunc(int id_now,const char *arg,const char* user,MYSQL *mysql)
{
    //设置返回值，在多参数情况下只保存最后一次失败的值
    int return_value = 0;
    char str[1024];
    strcpy(str,arg);
    int idx = 0;
    char *p[1024];
    p[idx++] = strtok(str," ");
    //printf("%s\n",p[0]);
    while((p[idx++] = strtok(NULL," ")) != NULL);
    //printf("%s\n",p[idx-1]);
    for(int i = 0; i < idx && p[i] != NULL; i++)
    {
        char name[1024] = {0};
        strcpy(name,p[i]);
        //传给getAbsolutePathId的name是去掉了要创建的文件夹的名字
        int id = getAbsolutePathId(id_now,name,user,mysql);
        //int id = id_now;
        //如果id对应的目录不存在，则创建失败
        if(id == -1)
        {
            return_value = -1;
            break;
        }
        //如果id对应的是文件，则创建失败；
        if(isDir(id,mysql) == 0)
        {
            return_value = -1;
            break;
        }
        //如果id对应的tomb==1，则删除失败
        if(isTomb1(id,mysql) == 1)
        {
            return_value = -1;
            break;
        }
        //如果id对应目录非空，则删除失败
        if(isEmpty(id,mysql) == 0)
        {
            return_value = -1;
            break;
        }
        //将int型转换成字符串型
        char str[20] = {0};
        sprintf(str,"%d",id);

        char sql[4096];
        bzero(sql,sizeof(sql));
        strcpy(sql,"update virtual_file set tomb = 1 where id = ");

        strcat(sql,str);
        printf("%s\n",sql);
        int qret = mysql_query(mysql,sql);
        if(qret != 0){
            fprintf(stderr,"error:%s\n", mysql_error(mysql));
            {
                return_value = -1;
                break;
            }
        }
    }
    return return_value;
}

//删除文件，先判断文件是否存在，不存在删除失败，是文件夹删除失败，tomb=1删除失败，否则将对应id的tomb参数置为1；
int removeFunc(int id_now,const char *arg,const char* user,MYSQL *mysql)
{
    //设置返回值，在多参数情况下只保存最后一次失败的值
    int return_value = 0;
    char str[1024];
    strcpy(str,arg);
    int idx = 0;
    char *p[1024];
    p[idx++] = strtok(str," ");
    //printf("%s\n",p[0]);
    while((p[idx++] = strtok(NULL," ")) != NULL);
    //printf("%s\n",p[idx-1]);
    for(int i = 0; i < idx && p[i] != NULL; i++)
    {
        char name[1024] = {0};
        strcpy(name,p[i]);
        //传给getAbsolutePathId的name是去掉了要创建的文件夹的名字
        int id = getAbsolutePathId(id_now,name,user,mysql);
        //int id = id_now;
        //如果id对应的文件不存在，则删除失败
        if(id == -1)
        {
            return_value = -1;
            break;
        }
        //如果id对应的是目录，则删除失败；
        if(isDir(id,mysql) == 1)
        {
            return_value = -1;
            break;
        }
        //如果id对应的tomb==1，则删除失败
        if(isTomb1(id,mysql) == 1)
        {
            return_value = -1;
            break;
        }
        //将int型转换成字符串型
        char str[20] = {0};
        sprintf(str,"%d",id);

        char sql[4096];
        bzero(sql,sizeof(sql));
        strcpy(sql,"update virtual_file set tomb = 1 where id = ");

        strcat(sql,str);
        printf("%s\n",sql);
        int qret = mysql_query(mysql,sql);
        if(qret != 0){
            fprintf(stderr,"error:%s\n", mysql_error(mysql));
            {
                return_value = -1;
                break;
            }
        }
    }
    return return_value;
}

